iT邦幫忙

2022 iThome 鐵人賽

DAY 26
1
Modern Web

[學習筆記] 邊學邊寫 JavaScript 30天系列 第 26

[學習筆記] 邊學邊寫 JavaScript 30天 (26):prototype I

  • 分享至 

  • xImage
  •  

今天內容

  • 物件導向 (ES6 class)
  • 物件導向 (ES5)

筆記

  • 物件導向(以ES6才有的class來寫)

    class Person {
      sayHello() {    
        console.log("Hello")
      }
    }
    var fang = new Person ()
    fang.sayHello()   //Hello
    

    class Person:Person 以大寫開頭
    sayHello():不用加function寫成function sayHello(),代表這是class裡面的一個method。

    將class視為一個設計圖,先去定義好一個行為。
    實際用這個class,加上new這個關鍵字去實體化這個設計圖。新增一個instance物件,讓這一個instance物件,能用.去操作到sayHello這個method。

    class Person {
      //setter
      setName(name) {
        this.name = name
      }
      sayHello() {
        console.log("Hello," + this.name)
      }
      //getter
      getName(name) {
        return this.name	
      }
    }
    var peopleA = new Person ()
    peopleA.setName ("fang")
    peopleA.sayHello()    //Hello,fang
    console.log(peopleA.getName())  //fang
    

    setName(setter)和getName(getter)是一種很常見來設置的用法。
    雖然 peopleA.name = "123" 直接.name可以改得到,但不建議這樣做,還是透過set/get來操作。

    上一段的var peopleA = new Person ()看起來像是一個function call其實可以直接傳參數進去。但上面的setName(name)不是function,要怎麼接收到?這個時候就要拿出 記憶吐司 我是說constructor建構子來初始化。

    class Person {
      constructor(name) {
        this.name = name
      }
      sayHello() {
        console.log(`Hello,${this.name}`)
      }
    }
    var peopleA = new Person ("fang")
    peopleA.sayHello()   //Hello,fang
    var peopleB = new Person ("路人甲")
    peopleB.sayHello()   //Hello,路人甲
    var peopleC = new Person ("路人乙")
    peopleC.sayHello()   //Hello,路人乙
    

    根據上面的class(設計圖),就能用new根據設計圖產生很多個新的instance(人)幾個都可以,並都能做一樣事情(sayHello)。

  • 物件導向 (ES6之前)

    function Person(name) {
      var myName = name
      return {
        getName: function() {
          return myName
        },
        sayHello: function() {
          console.log(myName)
        }
      }
    }
    var a = Person("aaa")
    a.sayHello()
    var b = Person("bbb")
    b.sayHello()
    console.log(a.sayHello === b.sayHello)  //false
    

    在早期要讓物件做到同一事的時候,這樣寫會讓每新增一個人都需要一個新的getName function。所以console.log(a.sayHello === b.sayHello) //false。但其實他們做的都是同一件事,這樣就有點消耗記憶體。

  • new:幾講這個之前可以先來講講JS歷史,以下文字引用Javascript繼承機制的設計思想 部分內容,想要更完整的介紹可以點連結。

    當初作者在設計時覺得沒必要設計得很複雜,這種語言只要能夠完成一些簡單操作就夠了,比如判斷用戶有沒有填寫表單。Javascript裡面所有的數據類型都是對象(object),這一點與Java非常相似。但是,他隨即就遇到了一個難題,到底要不要設計"繼承"機制呢?
    如果真的是一種簡易的腳本語言,其實不需要有"繼承"機制。
    但是,Javascript裡面都是對象,必須有一種機制,將所有對象聯繫起來。
    所以,Brendan Eich最後還是設計了"繼承"。
    但是,他不打算引入"類"(class)的概念,因為一旦有了"類",Javascript就是一種完整的面向對象編程語言了,這好像有點太正式了,而且增加了初學者的入門難度。他考慮到,C++和Java語言都使用new命令,生成實例。

    第一個範例所用的class也只是一個語法糖而已,與引用的文字內所說的"類"(class)的概念不一樣。
    (語法糖用詞是指寫的code更精簡,但底層操作都是同樣原理。語法糖對人類寫code更加友善)。

    function Person(name) {
      this.name = name
    }
    Person.prototype.getName = function() {
      return this.name
    }
    
    Person.prototype.sayHello = function() {
      console.log(this.name)
    }
    
    var a = new Person("aaa")
    a.sayHello()
    var b = new Person("bbb")
    b.sayHello()
    console.log(a.sayHello === b.sayHello)  //true
    

    加上prototypenew會把function Person(name)當作constructor來使用,使a和b都用了function Person(name)這個設計圖所以console.log(a.sayHello === b.sayHello) //true


參考資料


上一篇
[學習筆記] 邊學邊寫 JavaScript 30天 (25):Closure
下一篇
[學習筆記] 邊學邊寫 JavaScript 30天 (27):prototype II
系列文
[學習筆記] 邊學邊寫 JavaScript 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言